﻿using System;
using System.Collections;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Xml.Linq;
//añadidas por mi
using Persistencia_y_capa_de_negocio;
using System.Text.RegularExpressions;
using System.IO;

namespace webclonegame.FormulariosPublica
{
    public partial class registrarse : System.Web.UI.Page
    {
        /// <summary>
        /// Objeto de tipo ENUsuario, sera el usuario que alamacenare en caso de que se realice
        /// con exito el proceso de registro.
        /// </summary>
        protected ENUsuario usuario;
        /// <summary>
        /// Evento que se ejecuta siempre que se carga o recarga la página.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!this.IsPostBack)
            {
                ViewState["extension"] = "";
                ViewState["imagenCargada"] = false;
                RellenarListaAnyos();
                ListaAnos.SelectedIndex = -1;
                Image1.Width = 150;
                Image2.Width = 150;
                Image1.Height = 150;
                Image2.Height = 150;

            }
            tbNickname.Focus();
            
        }
        /// <summary>
        /// Rellena la lista desplegable ListaAnos con los años que puede tener un usuario
        /// </summary>
        protected void RellenarListaAnyos()
        {
            int contador;
            for (contador = 2003; contador >= 1900; contador--)
            {
                ListaAnos.Items.Add(contador.ToString());
            }

        }

        /// <summary>
        /// Este evento controla la accion del boton btCrearUsuario. Hace que se validen
        /// los datos y si estos son correctos segun lo definido, se crea y guarda un nuevo usuario
        /// asi como tambien se avanza a la siguiente vista del contro multiview
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void btCrearUsuario_Click(object sender, EventArgs e)
        {
            lbErrorImagen.Text = "";//Asi se borran los errores de imagen, puesto que no es necesario
            //cargar ninguna imagen.
            //Antes de esto hay que comprobar los campos y introducir el usuario en la BD
            if (Page.IsValid)
            {
                //Crear Usuario
                usuario = new ENUsuario();//Creo un nuevo usuario vacio
                usuario.NombreUsuario = tbNickname.Text.ToString();
                //La clave del usuario hemos de codificarla antes en md5.
                CodMD5 codificador = new CodMD5();
                usuario.PassUsuario = codificador.convertiraMD5(tbClave1.Text.ToString());
                usuario.EmailUsuario = tbEmail.Text.ToString();
                //Fecha de registro introducimos la actual.(Pero sin la hora)
                usuario.FechaRegUsuario = DateTime.Now.Date;

                //Ahora tengo que proporcionarles las coordenadas del cuadrante y de la
                //Base. Para ello voy a crear una función que las calcule de forma
                //aleatoria( comprobando que no hay ningún usuario ya con las mismas)
                int cuadx, cuady, basex, basey; //Contendran las coordenadas.
                cuadx = cuady = basex = basey = 0;
                GenerarCoordenadas(ref cuadx, ref cuady, ref basex, ref basey);
                usuario.CXBaseUsuario = basex;
                usuario.CYBaseUsuario = basey;
                usuario.CXCuadranteUsuario = cuadx;
                usuario.CYCuadranteUsuario = cuady;
                usuario.IDUsuario = -1; //Le doy el id -1 ya que un usuario no puede tener
                //ese id y por tanto no lo encontrara en la BD y creara uno nuevo. 
                //Crear el usuario en la BD.Si se crea pasar a la siguiente pagina.Y cargarlo
                //en una varibale session.Esto ultimo lo hacemos si el usuario decide empezar.

                //Guardar la imagen.Ajustarla antes en tamaño.(Incluso en formato y asi
                //Admitimos mas tipos.
                bool cargada = (bool)ViewState["imagenCargada"];
                string ext = (string)ViewState["extension"];
                if (cargada == true)
                {
                    string dirOrigen = Server.MapPath("./Avatar");
                    string filename = "avatar" + ext;
                    string origenPath = Path.Combine(dirOrigen, filename);
                    System.Drawing.Image avatar = System.Drawing.Image.FromFile(origenPath);
                    System.Drawing.Bitmap avatar2 = new System.Drawing.Bitmap(avatar, new System.Drawing.Size(50, 50));
                    string ruta = Server.MapPath("~");
                    ruta = ruta.Remove(ruta.LastIndexOf(@"webclonegame\"));
                    ruta = Path.Combine(ruta, @"clonegame\imagenes\usuarios");
                    string fDestino = usuario.NombreUsuario + ".png";
                    string desPath = Path.Combine(ruta, fDestino);
                    avatar2.Save(desPath, System.Drawing.Imaging.ImageFormat.Png);
                    string filename2 = usuario.NombreUsuario + ".png";
                    string desPath2 = Path.Combine(dirOrigen, filename2);
                    avatar2.Save(desPath2, System.Drawing.Imaging.ImageFormat.Png);
                }

                //
                if (CADUsuario.Instancia.InsertarUsuario(usuario))
                {
                    //Avanzar a la siguiente pagina.
                    MultiView1.ActiveViewIndex = 1;
                }
            }
        }


        /// <summary>
        /// Esta función me permite generar unas coordenadas de forma aletoria y que
        /// además conprueba que no se encuentren ya ocupadas por la base de otro
        /// usuario.
        /// </summary>
        /// <param name="cx">Coordenada x del cuadrante</param>
        /// <param name="cy">Coordenada y del cuadrante</param>
        /// <param name="bx">Coordenada x de la base</param>
        /// <param name="by">Coordenada y de la base</param>
        protected void GenerarCoordenadas(ref int cx, ref int cy, ref int bx, ref int by)
        {
            bool terminado = false;
            Random generador1 = new Random();
            while (!terminado)
            {
                //Generamos aletoriamente las coordenadas.
                cx = generador1.Next(0, 6);
                cy = generador1.Next(0, 6);
                bx = generador1.Next(0, 6);
                by = generador1.Next(0, 6);
                if (CADUsuario.Instancia.EstaOcupada(bx.ToString(), by.ToString(), cx.ToString(), cy.ToString(), -1) == false)
                {
                    terminado = true;
                }
            }
        }

        /// <summary>
        /// Validador del campo tbNickname.
        /// </summary>
        /// <param name="source"></param>
        /// <param name="args"></param>
        protected void ValidarCuenta_ServerValidate(object source, ServerValidateEventArgs args)
        {
            usuario = CADUsuario.Instancia.BuscarUsuarioPorCuenta(tbNickname.Text.ToString());
            if (tbNickname.Text == string.Empty)
            {
                args.IsValid = false;
                ValidarCuenta.ErrorMessage = "El nombre de usuario es obligatorio.";
            }
            else
            {
                if (usuario != null)
                {
                    //Si el usuario existe no se valida la página
                    args.IsValid = false;
                    ValidarCuenta.ErrorMessage = "El usuario ya exite. Por favor prueba con otro nombre.";
                }
            }
        }

        /// <summary>
        /// Validador del campo tbClave.
        /// </summary>
        /// <param name="source"></param>
        /// <param name="args"></param>
        protected void ValidarClave1_ServerValidate(object source, ServerValidateEventArgs args)
        {
            string mError="";
            if (ValidarClave(tbClave1.Text.ToString(),ref mError) == false)
            {
                args.IsValid = false;
                ValidarClave1.ErrorMessage = mError;
            }
        }

        /// <summary>
        /// Metodo que recibe con parametros una clace y un mensaje de ERROR y devuelve
        /// si la clave es valida.Una clave valida empieza por una letra y tiene entre 4 y 10
        /// caracteres alfanumericos.
        /// </summary>
        /// <param name="clave">La contraseña que el usuario quiere introducir</param>
        /// <param name="mensajeError">String pasado por referecia para alamacenar en el 
        /// un posible mensaje de error</param>
        /// <returns>True si la clave es valida segun lo que hemos definido</returns>
        protected bool ValidarClave(string clave, ref string mensajeError)
        {
            bool resultado = true;
            string patron= @"[a-zA-Z]\w{3,9}";//Definimos un patron de expresioón regular
            //de forma que la contraseña tiene que tener entre 4 y 10 caracteres, y uno de
            //ellos ha de ser una letra.
            if (clave == string.Empty)//Comprobamos que el campo no este vacio.
            {
                resultado = false;
                mensajeError = "La contraseña es obligatoria";
            }
            else{
                if(Regex.IsMatch(clave, patron) == false){
                    mensajeError = "La contraseña ha de empezar por una letra y debe contener entre 4 y 10 caracteres.";
                    resultado = false;
                }
            }
            return resultado;
        }

        /// <summary>
        /// Comprueba si las claves introducciodas en los text box Contraseña y Confirmar
        /// contraseña son las mismas.
        /// </summary>
        /// <param name="source"></param>
        /// <param name="args"></param>
        protected void ValidarClave2_ServerValidate(object source, ServerValidateEventArgs args)
        {
            if (tbClave1.Text.ToString() != tbClave2.Text.ToString())
            {
                ValidarClave2.ErrorMessage = "La clave introducida en el campo confirmación de clave no coincide con la clave anterior";
                args.IsValid = false;
            }
        }

        /// <summary>
        /// Validador del campo correo electronico. Llama a la función EmailEsValido(string)
        /// </summary>
        /// <param name="source"></param>
        /// <param name="args"></param>
        protected void ValidarEmail_ServerValidate(object source, ServerValidateEventArgs args)
        {
            if (tbEmail.Text.ToString() == string.Empty)
            {
                args.IsValid = false;
                ValidarEmail.ErrorMessage = "La dirección de correo electrónico es obligatoria";
            }
            else
            {
                if (!EmailEsValido(tbEmail.Text.ToString()))
                {
                    ValidarEmail.ErrorMessage = "La dirección de correo electrónico no es valida.";
                    args.IsValid = false;
                }
            }

        }

        /// <summary>
        /// Función que dado una cadena que contiene una dirección de email me dice si es una
        /// dirección correcta.
        /// </summary>
        /// <param name="correo"> Cadena que contiene el emial</param>
        /// <returns> Devuelve true si se trata de una direccion de email valida</returns>
        protected bool EmailEsValido(string correo)
        {
            return Regex.IsMatch(correo, @"^([\w-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([\w-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$");
        }

        /// <summary>
        /// Controla la acción asociada al boton CargarImagen. Permite cargar la imagen
        /// seleccionada en control fileUpload y mostrarla en el campo Avatar.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void btCargarImagen_Click(object sender, EventArgs e)
        {
            string clave1 = tbClave1.Text;
            string clave2 = tbClave2.Text;
            lbErrorImagen.Text = "";
            if (FileUpload1.HasFile)//Compruebo si se ha cargado algún archivo.
            {
                string fileExt = System.IO.Path.GetExtension(FileUpload1.FileName);

                if (fileExt == ".png" || fileExt == ".jpg" || fileExt == ".gif")//Compruebo que se trata de un archivo png
                {
                    try
                    {

                        string destDir = Server.MapPath("./Avatar");
                        string filename = "avatar" + fileExt;
                        string destPath = Path.Combine(destDir, filename);
                        //La idea es que para mostrar la imagen se guarda siempre en
                        //el mismo archivo, luego ya si se crea el usuario, la guardamos
                        //con su nombre en el directorio de las imagenes.
                        FileUpload1.PostedFile.SaveAs(destPath);
                        //Ahora mostrar la imagen
                        Avatar.ImageUrl = "./Avatar/avatar" + fileExt;
                        Avatar.Height = 100;
                        Avatar.Width = 100;
                        ViewState["extension"] = fileExt;
                        ViewState["imagenCargada"] = true;


                    }
                    catch (Exception ex)
                    {
                        lbErrorImagen.Text = "Error al cargar la imagen: \n" + ex.Message.ToString();
                    }
                    finally
                    {
                        tbClave1.Attributes.Add("value", clave1);
                        tbClave2.Attributes.Add("value", clave2);
                    }
                }
                else
                {
                    lbErrorImagen.Text = "Error. Solo se permiten archivos de imagen png, jpg o gif";
                }
            }
            else
            {
                lbErrorImagen.Text = "Error. No has seleccionado ninguna imagen";
            }
            tbClave1.Attributes.Add("value", clave1);
            tbClave2.Attributes.Add("value", clave2);

        }

        /// <summary>
        /// Controla la acción que genera el click sobre el boton empezar de la
        /// segunda página del mutiview.Si el usuario pulsa este boton accedera a la
        /// parte privada, ya que se ha registrado previamente.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void btEmpezar_Click(object sender, EventArgs e)
        {
            //obtengo el usuario de la bd para mayor seguridad
            ENUsuario usu = new ENUsuario();
            usu = CADUsuario.Instancia.BuscarUsuarioPorCuenta(tbNickname.Text);
            //Ahora creamos un objeto session que va a contener un objeto de tipo ENUsuario.
            if (usu != null)
            {
                Session["UsuarioActual"] = usu;
                Response.Redirect("~/FormulariosPrivada/resumen.aspx");
            }
        }

        /// <summary>
        /// Valida si se han aceptado los terminos y condiciones.
        /// </summary>
        /// <param name="source"></param>
        /// <param name="args"></param>
        protected void ValidarCondiciones_ServerValidate(object source, ServerValidateEventArgs args)
        {
            if (!cbCondiciones.Checked)
            {
                ValidarCondiciones.ErrorMessage = "Es obligatorio aceptar los términos y condiciones.";
                args.IsValid = false;
            }
            
        }




    }
}
